package com.song.osclient.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

public class BitmapUtil {
    public static Bitmap cut(Bitmap bitmap, int x, int y, int width, int height) {
        return Bitmap.createBitmap(bitmap, x, y, width, height, null, true);
    }

    public static Bitmap cut(Bitmap bitmap, Rect rect) {
        return cut(bitmap, rect.top, rect.left, rect.right - rect.left, rect.bottom - rect.top);
    }
    public static Bitmap cut(Bitmap bitmap, RectF rect) {
        return cut(bitmap, (int)rect.top, (int)rect.left, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top));
    }

    public static Bitmap getBitmapFromData(byte[] data) {
        return BitmapFactory.decodeByteArray(data, 0, data.length);
    }

    public static Bitmap rotateBitmap(Bitmap bitmap, int degree) {
        Matrix m = new Matrix();
        m.setRotate(degree, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
    }
    //图片灰化处理
    public Bitmap getGrayBitmap(Bitmap mBitmap) {
        Bitmap mGrayBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas mCanvas = new Canvas(mGrayBitmap);
        Paint mPaint = new Paint();
        //创建颜色变换矩阵
        ColorMatrix mColorMatrix = new ColorMatrix();
        //设置灰度影响范围
        mColorMatrix.setSaturation(0);
        //创建颜色过滤矩阵
        ColorMatrixColorFilter mColorFilter = new ColorMatrixColorFilter(mColorMatrix);
        //设置画笔的颜色过滤矩阵
        mPaint.setColorFilter(mColorFilter);
        //使用处理后的画笔绘制图像
        mCanvas.drawBitmap(mBitmap, 0, 0, mPaint);
        return mGrayBitmap;
    }

    public Bitmap ScaleBitmap(Bitmap mBitmap,float x) {
        int width = mBitmap.getWidth();
        int height = mBitmap.getHeight();

        Matrix matrix = new Matrix();
        matrix.preScale(0.75f, 0.75f);

        return Bitmap.createBitmap(mBitmap, 0, 0, width, height, matrix, true);
    }

    public Bitmap getRoundedBitmap(Bitmap mBitmap) {
        //创建新的位图
        Bitmap bgBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        //把创建的位图作为画板
        Canvas mCanvas = new Canvas(bgBitmap);

        Paint mPaint = new Paint();
        Rect mRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
        RectF mRectF = new RectF(mRect);
        //设置圆角半径为20
        float roundPx = 15;
        mPaint.setAntiAlias(true);
        //先绘制圆角矩形
        mCanvas.drawRoundRect(mRectF, roundPx, roundPx, mPaint);

        //设置图像的叠加模式
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //绘制图像
        mCanvas.drawBitmap(mBitmap, mRect, mRect, mPaint);

        return bgBitmap;
    }

    public static int getBitmapSize(Bitmap bitmap) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
            return bitmap.getByteCount();
        }
        return bitmap.getRowBytes() * bitmap.getHeight();
    }

    public static Bitmap scaleBitmap(Bitmap bitmap, float scale) {
        if (scale == 1.0f) {
            return bitmap;
        } else {
            return Bitmap.createScaledBitmap(bitmap, (int) (scale * (float) bitmap.getWidth()),
                    (int) (scale * (float) bitmap.getHeight()), true);
        }
    }

    public static Bitmap scaleBitmap(Bitmap bitmap, int maxSize) {
        int size = Math.max(bitmap.getWidth(), bitmap.getHeight());
        return scaleBitmap(bitmap, (float) maxSize / (float) size);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int width = options.outWidth;
        final int height = options.outHeight;
        float inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            float scaleW = (float) width / (float) reqWidth;
            float scaleH = (float) height / (float) reqHeight;
            inSampleSize = Math.max(scaleW, scaleH);
            Log.e("TEST", width + "," + height + "-" + inSampleSize);
            if (inSampleSize > 1.25 && inSampleSize < 2) inSampleSize = 2;
            else if (inSampleSize > 2.5 && inSampleSize < 4) inSampleSize = 4;
            else if (inSampleSize > 5.0 && inSampleSize < 8) inSampleSize = 8;
        }
        Log.e("TEST", width / inSampleSize + "," + height / inSampleSize + "-" + inSampleSize);
        return Math.round(inSampleSize);
    }

    public static Bitmap decodeBitmapFromFile(String filePath, int reqWidth, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }

    public static Bitmap decodeBitmap(byte[] data, int reqWidth, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, 0, data.length, options);
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeByteArray(data, 0, data.length, options);
    }


    public static void compress2File(Bitmap bitmap, File file, int MAX_IMAGE_SIZE) throws IOException {
        int length = getBitmapSize(bitmap);
        int quality = 100;
        ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
        while (length > MAX_IMAGE_SIZE && quality > 5) {
            try {
                bmpStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bmpStream.reset();
            quality -= 5;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bmpStream);
            length = bmpStream.size();
        }

        Log.e("TEST", "quality:" + quality);
        IOUtil.write2File(file, bmpStream.toByteArray());
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
            System.gc();
        }
    }

    public static byte[] bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    public static void recyleBitmap(Bitmap bitmap) {
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
            System.gc();
        }
    }
}
